package com.flaskpy.web.eternity.auth.jwt.util;


import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.flaskpy.web.eternity.auth.jwt.config.JwtConfigProperties;
import com.flaskpy.web.eternity.auth.jwt.entiry.JwtPayLoad;
import io.jsonwebtoken.*;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


public class TokenProvider  {
    @Autowired
    private JwtConfigProperties jwtConfigProperties;


    public void afterPropertiesSet() throws Exception {

    }

    /**
     * 对象转 jwtToken字符付
     * @param jwtSimpleDTO
     * @return
     */
    @SneakyThrows
    public String jwtContentToToken(JwtPayLoad jwtSimpleDTO) {

        String id= String.valueOf(System.currentTimeMillis())+ RandomUtil.randomString(4);
        return generalJWT(id,jwtSimpleDTO, jwtConfigProperties.getJwtExpireTime(), jwtConfigProperties.getSecret());

    }

    /**
     * 字符串 转 对象
     * @param token
     * @return
     * @throws JsonProcessingException
     */
    public JwtPayLoad tokeToJWTContentDTO(String token) throws JsonProcessingException {
        Claims claims=parseJWT(token, jwtConfigProperties.getSecret());
        String json=claims.getSubject();
        JwtPayLoad result = JSONUtil.toBean(json, JwtPayLoad.class);
        return result;
    }

//    public JwtPayLoad toJwtContentDTO(Authentication authentication) {
//
//        UserDetails userDetails=(UserDetails) authentication.getPrincipal();
//        JwtPayLoad jwtContentDTO=new JwtPayLoad();
//        jwtContentDTO.setUserName(userDetails.getUsername());
//        jwtContentDTO.setSessionId(StrUtil.uuid());
//        jwtContentDTO.setRoleOrAuthorityList(authentication.getAuthorities().stream().map(p->((GrantedAuthority) p).getAuthority()).collect(Collectors.toList()));
//
//        return jwtContentDTO;
//    }
//
//    public Authentication toAuthentication(JwtPayLoad jwtContentDTO) {
//
//        List<String> authentications = jwtContentDTO.getRoleOrAuthorityList();
//        authentications= authentications==null? Collections.emptyList():authentications;
//
//        List<SimpleGrantedAuthority> grantedAuthoritys = authentications.stream().map(p -> new SimpleGrantedAuthority(p)).collect(Collectors.toList());
//        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(jwtContentDTO.getUserName(),jwtContentDTO.getSessionId(),grantedAuthoritys);
//        return authenticationToken;
//
//    }
    /**
     * 生成token
     * @param id
     * @param subject
     * @param second
     * @param secret
     * @return
     * @throws JsonProcessingException
     */
    private   String generalJWT(String id,Object subject,Integer second,String secret) throws JsonProcessingException {

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();//生成JWT的时间
        String json=JSONUtil.toJsonStr(subject);
        //String json=JSON.toJSONString(subject);
        Date now = new Date(nowMillis);
        JwtBuilder builder = Jwts.builder()
                //唯一码，防重播攻击可以使用
                .setId(id)
                //密钥
                .signWith(signatureAlgorithm,secret)
                //载体
                .setSubject(json)
                //签发时间
                .setIssuedAt(now);
        if(second>0){
            //过期时间
            long expMillis = nowMillis + second*1000;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }
    /**
     *解释jwt
     * @param jwt   jwt字符串
     * @param secret    密钥
     * @return
     */
    private   Claims parseJWT(String jwt, String secret){
        Claims claims = Jwts.parser()  //得到DefaultJwtParser
                .setSigningKey(secret)         //设置签名的秘钥
                .parseClaimsJws(jwt).getBody();//设置需要解析的jwt
        return claims;
    }



}
